package jwd.util

import android.os.AsyncTask
import jwd.base.*
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLEncoder

/**
 * Created by udi on 17-7-30.
 */

data class AjaxResult(var msg: String = ""/*错误消息*/, var body: String = "", var status: Int = 0, var isJson: Boolean = false)

class AjaxTask<T>(var ajax: Ajax, var clazz: Class<T>, var sucessAction: ((T) -> Unit)? = null) : AsyncTask<String, Int, AjaxResult>() {

    override fun doInBackground(vararg args: String): AjaxResult {
        val urlConn: HttpURLConnection
        var ret = AjaxResult()

        try {
            var requestUrl = Config.Host + ajax.url;

            if (ajax.method == "POST" && ajax.postJson.any() && !ajax.url.contains("?")) {
                requestUrl += "?" + ajax.postJson.map { URLEncoder.encode(it.key, ajax.charset) + URLEncoder.encode(it.value, ajax.charset) }.joinToString("&")
            }




            // 新建一个URL对象
            val url = URL(requestUrl)
            // 打开一个HttpURLConnection连接

            urlConn = url.openConnection() as HttpURLConnection
        } catch(e: Exception) {
            ret.msg = e.message ?: "系统网络异常"
            return ret
        }


        try {
            // 设置连接主机超时时间
            urlConn.connectTimeout = 5 * 1000
            //设置从主机读取数据超时
            urlConn.setReadTimeout(5 * 1000)
            // 设置是否使用缓存  默认是true
            urlConn.setUseCaches(true)
            // 设置为Post请求
            urlConn.setRequestMethod(ajax.method)
            //urlConn设置请求头信息


            ajax.header.forEach {
                urlConn.setRequestProperty(it.key, it.value)
            }


            // 开始连接
            urlConn.connect()
            // 判断请求是否成功


            ret.status = urlConn.responseCode
            ret.body = urlConn.inputStream.GetString()
            //application/json;charset=UTF-8
            ret.isJson = urlConn.getHeaderField("Content-Type").indexOf("json") >= 0
            ret.msg = urlConn.errorStream.GetString()
        } catch(e: Exception) {
            ret.msg = e.message ?: "网络错误"
            return ret;
        } finally {
            // 关闭连接
            urlConn.disconnect()
        }
        return ret
    }

    override fun onPostExecute(result: AjaxResult?) {
        if (result == null) {
            return
        }

        if (this.sucessAction == null) {
            return
        }

        if (result.msg.isEmpty() == false) {
            Config.Activity.alert(result.msg)
            return
        }


        if (clazz.IsSimpleClass()) {
            if (clazz.name == "java.lang.String") {
                this.sucessAction!!(result.body as T)
                return
            }

            if (clazz == Int::class.java) {
                this.sucessAction!!(result.AsInt() as T)
            }

            Config.Activity.alert("不支持的类型 ${clazz.name}")
            return
        }


        var json = result.body.parseJson<T>(clazz);
        if (json != null) {
            return this.sucessAction!!(json)
        }
    }
}


//链式调用
class Ajax(var url: String) {

    var method: String = "POST"
    var postJson: StringMap = StringMap()


    var charset: String = "utf-8";
    var header: StringMap = StringMap()


    init {
        header["Accept"] = "application/json";
        header["Content-Type"] = "application/json;charset=utf-8";
        header["Connection"] = "Keep-Alive";
    }


    fun header(key: String, value: String): Ajax {
        this.header[key] = value
        return this;
    }


    inline fun <reified T> doGet(noinline act: (T) -> Unit) {
        this.method = "GET"
        var ajax = AjaxTask<T>(this, T::class.java, act)

        ajax.execute()
    }

    inline fun <reified T> doPost(noinline act: (T) -> Unit) {
        doPost(StringMap(), act)
    }

    inline fun <reified T> doPost(postJson: StringMap, noinline act: (T) -> Unit) {
        this.postJson = postJson
        this.method = "POST"

        var ajax = AjaxTask<T>(this, T::class.java, act)
        ajax.execute()
    }
}